package in.shadowfax.proswipebutton;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.element.ShapeElement;

public class UiUtils {

    public static void animateFadeHide(Component view) {
        if (view != null && view.getVisibility() == Component.VISIBLE) {
            AnimatorProperty animatorProperty = view.createAnimatorProperty();
            animatorProperty.setDuration(500);
            animatorProperty.alphaFrom(1);
            animatorProperty.alpha(0);
            animatorProperty.setCurveType(Animator.CurveType.ACCELERATE);
            animatorProperty.start();
            view.setVisibility(Component.HIDE);
        }
    }

    public static void animateFadeShow(Component view) {
        if (view.getVisibility() != Component.VISIBLE) {
            AnimatorProperty animatorProperty = view.createAnimatorProperty();
            animatorProperty.setDuration(500);
            animatorProperty.alphaFrom(0);
            animatorProperty.alpha(1);
            animatorProperty.setCurveType(Animator.CurveType.ACCELERATE);
            animatorProperty.start();
            view.setVisibility(Component.VISIBLE);
        }
    }

    /**
     * According to the start rounded and end rounded,
     * construct the value change animation of the rounded
     *
     * @param start Starting rounded size
     * @param end   End rounded size
     * @return Animation of rounded corner value change
     */
    public static AnimatorValue buildCornerValueAnim(float start, float end, ShapeElement element) {
        if (element == null) {
            return null;
        }
        AnimatorValue cornerAnimation = new AnimatorValue();
        cornerAnimation.setValueUpdateListener((animatorValue, v) -> element.setCornerRadius((float) UiUtils.calAnimValue(start, end, v)));
        return cornerAnimation;
    }

    /**
     * According to the start width and end width,
     * build an animation of the value change of the control width
     *
     * @param start Starting width
     * @param end   End width
     * @return Animated width value change
     */
    public static AnimatorValue buildWidthValueAnim(int start, int end, Component component) {
        if (component == null) {
            return null;
        }
        AnimatorValue anim = new AnimatorValue();
        anim.setValueUpdateListener((animatorValue, v) -> {
            ComponentContainer.LayoutConfig layoutParams = component.getLayoutConfig();
            if (layoutParams != null) {
                layoutParams.width = (int) UiUtils.calAnimValue(start, end, v);
                component.setLayoutConfig(layoutParams);
            }
        });
        return anim;
    }

    /**
     * According to the starting height and ending height,
     * construct the value change animation of the control height
     *
     * @param start Starting height
     * @param end   End height
     * @return Animation of height value change
     */
    public static AnimatorValue buildHeightValueAnim(int start, int end, Component component) {
        if (component == null) {
            return null;
        }
        AnimatorValue anim = new AnimatorValue();
        anim.setValueUpdateListener((animatorValue, v) -> {
            ComponentContainer.LayoutConfig layoutParams = component.getLayoutConfig();
            if (layoutParams != null) {
                layoutParams.height = (int) UiUtils.calAnimValue(start, end, v);
                component.setLayoutConfig(layoutParams);
            }
        });
        return anim;
    }

    /**
     * According to the current value of the animation,
     * calculate the actual value between the start value and the end value
     *
     * @param start Starting value
     * @param end   End value
     * @param curr  The current value of the animation
     * @return Actual value
     */
    public static double calAnimValue(double start, double end, double curr) {
        return start + (end - start) * curr;
    }

    /**
     * Animation state change listener
     */
    public static class AnimationStateListener implements Animator.StateChangedListener {

        @Override
        public void onStart(Animator animator) {

        }

        @Override
        public void onStop(Animator animator) {

        }

        @Override
        public void onCancel(Animator animator) {

        }

        @Override
        public void onEnd(Animator animator) {

        }

        @Override
        public void onPause(Animator animator) {

        }

        @Override
        public void onResume(Animator animator) {

        }
    }
}
